"""
dream 写的链接mysql的类
链接数据库的方式二
配置都在这个文件中
"""
import mysql.connector

class OpenDb:
    # 连接配置
    config = {
        'host': 'localhost',
        'user': 'root',
        'password': 'dreamren',
        'database': 'dream_nisshinkyo_study',
        'port': 3306,
        'raise_on_warnings': True
    }
    # print(config)
    def __init__(self):
        """
        初始化数据库连接
        :param host: MySQL 服务器地址
        :param user: 数据库用户名
        :param password: 数据库用户密码
        :param database: 要使用的数据库名
        """
        try:
            #  `mysql.connector.connect()` 函数需要接收独立的参数（如 `user`, `password`, `host` 等），而将配置保存在字典中再用 `**` 解包，可以让代码更整洁、易于管理
            self.connection = mysql.connector.connect(**self.config)
            # dictionary=True 以字典格式返回，否则以元组形式返回数据
            # buffered=True 采用缓冲模式，所有行都会立即读取以提高处理速度，占用更多内存，适合处理小到中等规模的数据
            self.cursor = self.connection.cursor(dictionary=True)
            # print("成功连接到数据库")
        except mysql.connector.Error as err:
            print(f"数据库连接失败: {err}")
            exit()

    
    def select_data(self, table_name, field='*', condition=None):
        """
        从指定表中查询数据
        :param table_name: 要查询数据的表名
        :param condition: 查询条件，如 'age > 20'，可选参数
        :return: 查询结果列表
        """
        if not table_name:
            return "表名为空"
        if condition:
            select_query = f"SELECT {field} FROM {table_name} WHERE {condition}"
        else:
            select_query = f"SELECT {field} FROM {table_name}"
        try:
            self.cursor.execute(select_query)
            results = self.cursor.fetchall()
            return results
        
        except mysql.connector.Error as err:
            print(f"查询数据时出错: {err}")
            # 发生错误时回滚事务
            self.connection.rollback()
            exit()
            # return []


    def insert_data(self, table_name, data):
        """
        向指定表中插入数据
        :param table_name: 要插入数据的表名
        :param data: 插入的数据，字典形式，如 {'name': 'John', 'age': 25}
        """
        if not table_name:
            return "表名为空"
        if not data:
            return "值为空"
        columns = ', '.join(data.keys())
        placeholders = ', '.join(['%s'] * len(data))
        values = tuple(data.values())
        insert_query = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
        try:
            self.cursor.execute(insert_query, values)
            # 获取受影响的行数
            rows_affected = self.cursor.rowcount
            # 获取最后插入行的 ID
            last_id = self.cursor.lastrowid
            # 提交事务
            self.connection.commit()
            # 返回新ID
            return last_id
            # print("数据插入成功")
        except mysql.connector.Error as err:
            print(f"插入数据时出错: {err}")
            exit()


    def update_data(self, table_name, set_values, condition):
        """
        更新指定表中的数据
        :param table_name: 要更新数据的表名
        :param set_values: 要更新的字段和值，字典形式，如 {'name': 'Alice', 'age': 26}
        :param condition: 更新条件，如 'id = 1'
        """
        if not table_name:
            return "表名为空"
        if not set_values:
            return "值为空"
        if not condition:
            return "条件为空"
        set_clause = ', '.join([f"{key} = %s" for key in set_values])
        values = tuple(set_values.values())
        update_query = f"UPDATE {table_name} SET {set_clause} WHERE {condition}"
        try:
            self.cursor.execute(update_query, values)
            # 检查受影响的行数
            affected_rows = self.cursor.rowcount
            # 提交事务
            self.connection.commit()
            # 返回受影响的行数
            return affected_rows
            # print("数据更新成功")
        except mysql.connector.Error as err:
            print(f"更新数据时出错: {err}")
            # 发生错误时回滚事务
            self.connection.rollback()
            exit()


    def delete_data(self, table_name, condition):
        """
        从指定表中删除数据
        :param table_name: 要删除数据的表名
        :param condition: 删除条件，如 'id = 1'
        """
        if not table_name:
            return "表名为空"
        if not condition:
            return "条件为空"
        delete_query = f"DELETE FROM {table_name} WHERE {condition}"
        try:
            self.cursor.execute(delete_query)
            self.connection.commit()
            print("数据删除成功")
        except mysql.connector.Error as err:
            print(f"删除数据时出错: {err}")
            exit()


    def close_connection(self):
        """
        关闭数据库连接和游标
        """
        if self.cursor:
            self.cursor.close()
        if self.connection:
            self.connection.close()
        print("数据库连接已关闭")

    
    def validation_char(self):
        """
        执行时需要输入指定字符才能继续
        """
        while True:
            user_input = input("请输入执行秘钥：")
            if user_input=='dreamren':
                print('秘钥验证通过')
                return 'success'
            elif user_input=='exit':
                print('主动结束，程序未执行')
                exit()
            else:
                print("✘ 秘钥无效，请重新输入输入。 ★ 输入：exit 结束程序")


    def create_table(self, table_name, columns, character_set='utf8mb4'):
        """
        创建数据库表，有库了，新建一个表
        :param table_name: 要创建的表名
        :param columns: 表的列定义，如 'id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255)'
        :param character_set: CHARACTER SET utf8mb4
        MySQL 为了逐步过渡到更统一的字符集使用方式，计划在未来版本中将 utf8 作为 utf8mb4 的别名。为了避免在未来版本升级时出现兼容性问题，MySQL 会在你使用 utf8 时给出这个警告。现在创建表时指定的 utf8 字符集替换为 utf8mb4
        """
        print(table_name)
        if not table_name:
            return "表名为空"
        if not columns:
            return "列定义为空"
        # 请求用户输入秘钥
        valid = self.validation_char()

        # 秘钥正确，继续执行下面的代码
        try:
            # 标准的 SQL 语法并不直接支持 IF NOT EXISTS 来返回一个状态或执行结果
            create_table_query = f"CREATE TABLE IF NOT EXISTS {table_name} ({columns}) CHARACTER SET {character_set}"
            self.cursor.execute(create_table_query)
            self.connection.commit()
            print(f"表 {table_name} 创建成功")
        except mysql.connector.Error as err:
            print(f"创建表时出错: {err}")
            exit()


    def truncate_table(self, table_name):
        """
        截断表
        :param table_name: 要截断的表名，慎重使用
        """
        if not table_name:
            return "表名为空"
        # 请求用户输入秘钥
        valid = self.validation_char()

        # 秘钥正确，继续执行下面的代码
        try:
            truncate_table_query = f"TRUNCATE TABLE {table_name}"
            self.cursor.execute(truncate_table_query)
            self.connection.commit()
            print(f"✔ 表 {table_name} 截断成功")
        except mysql.connector.Error as err:
            print(f"截断表时出错: {err}")
            exit()

# ***************

"""
使用示例：
from dream_class.ConnDb import OpenDb
db = OpenDb()
results = db.select_data("meeting_school_library", 'school_id,school_name', 'school_id<50')
print(results)
# for row in results:
#     print(row)
"""
# # 以下是使用示例
# from dream_class.ConnDb import OpenDb
# db = OpenDb()
# if __name__ == "__main__":
#     # 创建表
#     db.create_table("students", "id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), age INT")

#     # 插入数据
#     student_data = {"name": "张三", "age": 20}
#     db.insert_data("students", student_data)

#     # 查询数据
#     results = db.select_data("students")
#     for row in results:
#         print(row)

#     # 更新数据
#     update_values = {"age": 21}
#     db.update_data("students", update_values, "name = '张三'")

#     # 删除数据
#     db.delete_data("students", "name = '张三'")

#     # 关闭数据库连接
#     db.close_connection()

